package org.duang.db.mongo.parser;

import java.lang.reflect.Field;

import org.bson.types.ObjectId;
import org.duang.db.IdEntity;
import org.duang.db.annotation.Id;
import org.duang.db.annotation.Vo;
import org.duang.db.annotation.VoColl;
import org.duang.db.mongo.parser.decode.Decoder;
import org.duang.db.mongo.parser.decode.PropertyDecoder;
import org.duang.db.mongo.parser.decode.VoCollDecoder;
import org.duang.db.mongo.parser.decode.VoDecoder;
import org.duang.kit.ClassKit;
import org.duang.kit.DataType;
import org.duang.kit.ObjectKit;
import org.duang.kit.Reflections;
import org.duang.kit.ToolsKit;
import org.duang.kit.UrlKit;

import com.mongodb.DBObject;

/**
 *  DBObject Convetor Entity Factory
 * @author laotang
 *
 */
public class DecodeConvetor {
	
	public static <T> T convetor(Class<T> clazz, DBObject dbo) {
		if(ToolsKit.isEmpty(dbo)) return null;
		Field[] fields = ClassKit.getFields(clazz);
		if(ToolsKit.isEmpty(fields)) return null;
		T obj = ClassKit.createConst(clazz);
		for (int i = 0; i < fields.length; i++) {
			if(EncodeConvetor.ID_FIELD.equalsIgnoreCase( fields[i].getName() )){				
				Object odb = dbo.get(IdEntity.ID_FIELD);
				if(ToolsKit.isEmpty(odb))  continue;
				if(fields[i].isAnnotationPresent(Id.class)){
					Reflections.setFieldValue(obj, fields[i], ((ObjectId)odb).toString());
				} else {					
					try{
						Reflections.setFieldValue(obj, fields[i], odb);
					} catch ( Exception e){
						//在生产线上，可能会出现字段值是int，但数据库里的是String的情况，所以添加以下转换代码
						//用sping-mongodb.jar时可能会出现，因为entity声明为id的话，在保存到库里，可能会自己转为String
						String tmpId = ((ObjectId)odb).toString();
						Class<?> typeCls = fields[i].getType();
						if(DataType.isInteger(typeCls) || DataType.isIntegerObject(typeCls)) {
							ObjectKit.setField(obj, fields[i], Integer.parseInt(tmpId));
						} else if(DataType.isLong(typeCls) || DataType.isLongObject(typeCls)) {
							ObjectKit.setField(obj, fields[i], Long.parseLong(tmpId));
						} else if(DataType.isFloat(typeCls) || DataType.isFloatObject(typeCls)) {
							ObjectKit.setField(obj, fields[i], Float.parseFloat(tmpId));
						} else if(DataType.isDouble(typeCls) || DataType.isDoubleObject(typeCls)) {
							ObjectKit.setField(obj, fields[i], Double.parseDouble(tmpId));
						}
					}
				}
			}
			else {
				Decoder decoder = parser(dbo, fields[i]);
				decoder.setObj(obj);
				UrlKit.addHostSite(obj, fields[i], decoder.getFieldValue());//添加OSS域名
			}
		}
		return obj;
	}
	
	private static Decoder parser(DBObject dbo, Field field) {
		Decoder decoder = null;
		if(field.getAnnotation(Vo.class) != null){		
				decoder = new VoDecoder(dbo, field);	
		}else if(field.getAnnotation(VoColl.class) != null){		
				decoder = new VoCollDecoder(dbo, field);	
		}else{
			decoder = new PropertyDecoder(dbo, field);
		}
		return decoder;
	}
	
	
	
}
